package com.lzq.model.explain;

import java.util.HashMap;
import java.util.Map;

/**
 * @author : modify
 * @version : v1.0
 * @description :
 * @createTime : 2022/11/29 20:21
 * @updateUser : modify
 * @updateTime : 2022/11/29 20:21
 * @updateRemark : 解释器模式
 */
public abstract class AbstractExpression {
    /**
     * 计算
     *
     * @param context
     * @return int
     */
    public abstract int interpret(Context context);
}

class Variable extends AbstractExpression {
    private String name;

    public Variable(String name) {
        this.name = name;
    }

    @Override
    public int interpret(Context context) {
        return context.getValue(this);
    }

    @Override
    public String toString() {
        return name;
    }
}

/**
 * 加法
 */
class Plus extends AbstractExpression {
    private AbstractExpression left;
    private AbstractExpression right;

    public Plus(AbstractExpression left, AbstractExpression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret(Context context) {
        return left.interpret(context) + right.interpret(context);
    }

    @Override
    public String toString() {
        return "(" + left.toString() + " + " + right.toString() + ")";
    }
}

/**
 * 减法
 */
class Minus extends AbstractExpression {
    private AbstractExpression left;
    private AbstractExpression right;

    public Minus(AbstractExpression left, AbstractExpression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret(Context context) {
        return left.interpret(context) - right.interpret(context);
    }

    @Override
    public String toString() {
        return "(" + left.toString() + " - " + right.toString() + ")";
    }
}

class Context {
    private Map<Variable, Integer> map = new HashMap<Variable, Integer>();

    public void assign(Variable var, Integer value) {
        map.put(var, value);
    }

    public Integer getValue(Variable var) {
        return map.get(var);
    }
}

class Test {
    public static void main(String[] args) {
        Context context = new Context();

        Variable a = new Variable("a");
        Variable b = new Variable("b");
        Variable c = new Variable("c");
        Variable d = new Variable("d");

        context.assign(a, 1);
        context.assign(b, 2);
        context.assign(c, 3);
        context.assign(d, 4);

        AbstractExpression
                expression = new Minus(a, new Plus(c, new Minus(b, d)));
        int res = expression.interpret(context);
        System.out.println(expression.toString());
        System.out.println(res);

    }
}
